﻿using Coding4Fun.MissionControl.WP.Misc;
using Coding4Fun.MissionControl.WP.Models;
using Coding4Fun.Toolkit.Storage;
using System.Windows;

namespace Coding4Fun.MissionControl.WP.ViewModels
{
    public class CommandViewModel
    {
        static CommandViewModel instance = null;
        static readonly object padlock = new object();

        public CommandViewModel()
        {
            DeleteCommandCommand = new RelayCommand(DeleteCommand);
            DeleteSetCommand = new RelayCommand(DeleteSet);
            RemoveFromQuickLaunchCommand = new RelayCommand(RemoveFromQuickLaunch);
            AddToQuickLaunchCommand = new RelayCommand(AddToQuickLaunch);
            SelectServerCommand = new RelayCommand(SelectServer);
            SelectSetCommand = new RelayCommand(SelectSet);
            RemoveServerCommand = new RelayCommand(RemoveServer);
        }

        public static CommandViewModel Instance
        {
            get
            {
                lock (padlock)
                {
                    if (instance == null)
                    {
                        instance = new CommandViewModel();
                    }
                    return instance;
                }
            }
        }

        public RelayCommand DeleteSetCommand { get; private set; }
        private void DeleteSet(object set)
        {
            string currentSet = set.ToString();
            CollectionHelper.RemoveTrailingFavorites(x => x.ParentSet == currentSet && 
                x.ServerLocation == CommonViewModel.Instance.CurrentServer.Location);

            Deployment.Current.Dispatcher.BeginInvoke(async () =>
            {
                if (MessageBox.Show("Are you sure you want to delete the " + currentSet + " set?", "Remove Set",
                    MessageBoxButton.OKCancel) == MessageBoxResult.OK)
                {
                    CommonViewModel.Instance.IsWaiting = true;

                    bool commandSent = await CommonViewModel.Instance.CommandClient.SendCommand(CommonViewModel.Instance.CurrentServer.Location,
                        Constants.COMMAND_DELETE_SET, currentSet);
                    if (!commandSent)
                    {
                        Alert.Send(Constants.MESSAGE_SERVER_CONNECT_FAIL);
                        CommonViewModel.Instance.IsWaiting = false;
                    }
                }
            });
        }

        public RelayCommand DeleteCommandCommand { get; private set; }
        private void DeleteCommand(object command)
        {
            string currentCommand = command.ToString();
            CollectionHelper.RemoveTrailingFavorites(x => x.ParentSet == CommonViewModel.Instance.CurrentSet &&
                x.ServerLocation == CommonViewModel.Instance.CurrentServer.Location &&
                x.CommandName == currentCommand);

            Deployment.Current.Dispatcher.BeginInvoke(async () =>
                {
                    if (MessageBox.Show("Are you sure you want to delete the " + currentCommand + " command?", "Remove Command",
                        MessageBoxButton.OKCancel) == MessageBoxResult.OK)
                    {
                        CommonViewModel.Instance.IsWaiting = true;

                        bool commandSent = await CommonViewModel.Instance.CommandClient.SendCommand(
                            CommonViewModel.Instance.CurrentServer.Location,
                            string.Format(Constants.COMMAND_DELETE_COMMAND, CommonViewModel.Instance.CurrentSet), currentCommand);
                        if (!commandSent)
                        {
                            Alert.Send(Constants.MESSAGE_SERVER_CONNECT_FAIL);
                            CommonViewModel.Instance.IsWaiting = false;
                        }
                    }
                });
        }

        public RelayCommand RemoveServerCommand { get; private set; }
        private void RemoveServer(object server)
        {
            Deployment.Current.Dispatcher.BeginInvoke(() =>
                {
                    var result = MessageBox.Show("Are you sure you want to remove this server? This will also remove all the favorites that are associated with it.",
                        "Remove Server", MessageBoxButton.OKCancel);

                    if (result == MessageBoxResult.OK)
                    {
                        CollectionHelper.RemoveServer(server as Server);
                    }
                });
        }

        public RelayCommand RemoveFromQuickLaunchCommand { get; private set; }
        private void RemoveFromQuickLaunch(object favorite)
        {
            Favorite currentFavorite = favorite as Favorite;
            MainPageViewModel.Instance.Favorites.Remove(currentFavorite);
            Serialize.Save(Constants.FAVORITES_FILE, MainPageViewModel.Instance.Favorites);
        }

        public RelayCommand AddToQuickLaunchCommand { get; private set; }
        private void AddToQuickLaunch(object commandName)
        {
            Favorite favorite = new Favorite();
            favorite.CommandName = commandName.ToString();
            favorite.ParentSet = CommonViewModel.Instance.CurrentSet;
            favorite.ServerLocation = CommonViewModel.Instance.CurrentServer.Location;

            MainPageViewModel.Instance.Favorites.Add(favorite);
            Serialize.Save(Constants.FAVORITES_FILE, MainPageViewModel.Instance.Favorites);

            Deployment.Current.Dispatcher.BeginInvoke(() =>
            {
                MessageBox.Show(string.Format("{0} has been added to the Quick Launch panel.", favorite.CommandName), "Add To Quick Launch", MessageBoxButton.OK);
            });
        }

        public RelayCommand SelectServerCommand { get; private set; }
        private async void SelectServer(object server)
        {
            CommonViewModel.Instance.IsWaiting = true;
            CommonViewModel.Instance.CurrentServer = (Server)server;

            bool result = await CommonViewModel.Instance.CommandClient.SendCommand(CommonViewModel.Instance.CurrentServer.Location, 
                Constants.COMMAND_SERVER_HELLO, string.Empty);
            if (!result)
            {
                Alert.Send(Constants.MESSAGE_SERVER_CONNECT_FAIL);
                CommonViewModel.Instance.CurrentServer = null;

                CommonViewModel.Instance.IsWaiting = false;
            }
        }

        public RelayCommand SelectSetCommand { get; private set; }
        private async void SelectSet(object commandName)
        {
            CommonViewModel.Instance.CurrentSet = commandName.ToString();
            CommonViewModel.Instance.IsWaiting = true;

            bool commandSent = await CommonViewModel.Instance.CommandClient.SendCommand(CommonViewModel.Instance.CurrentServer.Location, 
                Constants.COMMAND_GET_COMMANDS, CommonViewModel.Instance.CurrentSet);
            if (!commandSent)
            {
                Alert.Send(Constants.MESSAGE_SERVER_CONNECT_FAIL);
                CommonViewModel.Instance.IsWaiting = false;
            }
        }

        internal void HandleOverlay(System.ComponentModel.CancelEventArgs e)
        {
            if (CommonViewModel.Instance.IsWaiting)
            {
                CommonViewModel.Instance.CommandClient.AbandonAttempt();
                CommonViewModel.Instance.IsWaiting = false;
                e.Cancel = true;
            }
        }
    }
}
